﻿using System;
using System.Windows.Forms;

namespace POS.UI.UserControls
{
    public partial class NumericTextBox : TextBox
    {
        #region Declarations

        public string Format { get; set; }
        public bool AllowNegative { get; set; }

        #endregion

        #region Constructors

        public NumericTextBox()
        {
            Format = "#,##0.00";
            AllowNegative = false;
        }

        #endregion

        
        public bool TryGetValue(out decimal data)
        {
            return decimal.TryParse(RemoveLiterals(Text), out data);
        }

        public decimal Value
        {
            get
            {
                decimal result;
                TryGetValue(out result);
                return result;
            }
            set
            {
                base.Text = ReplaceLeadingZeros(value.ToString(Format));
            }
        }

        private static string RemoveLiterals(string data)
        {
            return data != null ? data.Replace(" ", "").Replace(",", "") : "";
        }

        protected override void OnValidated(EventArgs e)
        {
            decimal data;
            if (TryGetValue(out data))
            {
                base.Text = ReplaceLeadingZeros(data.ToString(Format));
            }
            base.OnValidated(e);
        }

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                decimal data;
                if (decimal.TryParse(RemoveLiterals(value), out data))
                {
                    base.Text = ReplaceLeadingZeros(data.ToString(Format));
                }
                else
                {
                    base.Text = value;
                }
            }
        }

        private bool VerifyInput(Keys key)
        {
            switch (key)
            {
                case (Keys)46:      // Period  '.':
                    return (Format.IndexOf((char) key) != -1 && Text.IndexOf((char) key) == -1);

                case (Keys)45:      // Minus  '-':                    
                    return (AllowNegative && Text.IndexOf((char)key) == -1 && SelectionStart == 0);
            }
            return false;
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            bool keyValid;
            var key = (Keys)e.KeyChar;
            switch (key)
            {
                case Keys.Back: 
                case Keys.D0:
                case Keys.D1:
                case Keys.D2:
                case Keys.D3:
                case Keys.D4:
                case Keys.D5:
                case Keys.D6:
                case Keys.D7:
                case Keys.D8:
                case Keys.D9:
                    keyValid = true;
                    break;
                case (Keys)46:      // Period  '.'
                case (Keys)45:      // Minus   '-'
                    keyValid = VerifyInput(key);
                    break;
                default:
                    keyValid = false;
                    break;
            }
            e.Handled = !keyValid;
        }

        protected static string ReplaceLeadingZeros(string data)
        {
            char[] chars = data.ToCharArray();

            for (int i = 0; i < chars.Length; i++)
            {
                if (chars[i] != ' ')
                {
                    if (chars[i] == '0')
                        chars[i] = (char)0;
                    else
                        break;
                }
            }
            return new string(chars);
        }
    }
}
